Editing Polygon Parts
QuickDraw GX provides six functions that allow sophisticated editing of geometric shapes:
This section gives examples of the
- The
GXGetPolygonParts
andGXSetPolygonParts
functions allow you to extract information from a polygon geometry, replace information in the geometry, remove information in the geometry, and insert new information in the geometry.- The
GXGetPathParts
andGXSetPathParts
functions allow you to extract, replace, remove, and insert information in a path shape's geometry.- The
GXGetShapeParts
andGXSetShapeParts
functions allow you to extract, replace, remove, and insert information in any shape's geometry.
GXGetPolygonParts
andGXSetPolygonParts
functions. The next two sections show how to edit path shape geometries and shape geometries in general.Listing 2-27 creates a polygon shape with two contours. Later examples in this section use this polygon shape to demonstrate editing polygon parts.
Listing 2-27 Creating a polygon shape with two contours
void CreateTwoAngles(void) { gxShape aPolygonShape; static long twoAngleGeometry[] = {2, /* number of contours */ 3, /* number of points */ ff(100), ff(150), ff(50), ff(100), ff(100), ff(50), 3, /* number of points */ ff(200), ff(50), ff(250), ff(100), ff(200), ff(150)}; aPolygonShape = GXNewPolygons((gxPolygons *) twoAngleGeometry); GXSetShapeFill(aPolygonShape, gxOpenFrameFill); GXDrawShape(aPolygonShape); GXDisposeShape(aPolygonShape); }The result of this sample function is shown in Figure 2-52.Figure 2-52 A polygon shape with two contours
The
GXGetPolygonParts
function allows you to extract geometric points from the geometry of an existing polygon shape and put them into a new polygon geometry. This function takes four parameters:
The
- a reference to the existing polygon shape
- the index of the first desired geometric point
- the number of geometric points to include
- a pointer to a polygon geometry in which to store the extracted geometric points
GXGetPolygonParts
function returns as its function result the number of bytes necessary to contain the extracted polygon. Therefore, you typically callGXGetPolygonParts
twice--once to determine the size of extracted polygon and once to extract the polygon. For example, if you declare the variable
long byteCount;you could determine the number of bytes necessary to extract the top half of the polygon geometry in Figure 2-52 using this line of code:
byteCount = GXGetPolygonParts(aPolygonsShape, 2, 4, nil);In this example, setting the final parameter tonil
indicates that you want to determine the number of bytes necessary to hold the extracted polygon geometry, but you do not want to actually extract the polygon geometry. The values of 2 and 4 for the second and third parameters indicate that theGXGetPolygonParts
function should determine the number of bytes necessary to hold an extracted polygon geometry that contains geometric points 2, 3, 4, and 5 from the polygon geometry in Figure 2-52.You can then use this byte count to allocate enough memory to hold the extracted polygon geometry:
gxPolygons *topHalfGeometry; topHalfGeometry = (gxPolygons *) NewPtr(byteCount);Finally, you can extract the polygon geometry by callingGXGetPolygonParts
again:
GXGetPolygonParts(aPolygonsShape, 2, 4, topHalfGeometry);The sample function in Listing 2-28 creates the polygon shape from the previous example, extracts the second through the fifth geometric points and puts them into a separate geometry, and then replaces the geometry of the original polygon shape with the extracted geometry.Listing 2-28 Extracting part of a polygon shape
void ExtractTopPartOfPolygon(void) { gxShape aPolygonShape; static long twoAngleGeometry[] = {2, /* number of contours */ 3, /* number of points */ ff(100), ff(150), ff(50), ff(100), ff(100), ff(50), 3, /* number of points */ ff(200), ff(50), ff(250), ff(100), ff(200), ff(150)}; long byteCount; gxPolygons *topHalfGeometry; aPolygonShape = GXNewPolygons((gxPolygons *) twoAngleGeometry); GXSetShapeFill(aPolygonShape, gxOpenFrameFill); byteCount = GXGetPolygonParts(aPolygonShape, 2, 4, nil); topHalfGeometry = (gxPolygons *) NewPtr(byteCount); GXGetPolygonParts(aPolygonShape, 2, 4, topHalfGeometry); GXSetPolygons(aPolygonShape, topHalfGeometry); GXDrawShape(aPolygonShape); GXDisposeShape(aPolygonShape); }The resulting polygon shape is shown in Figure 2-53.Figure 2-53 A polygon shape extracted from a larger polygon shape
Compare this polygon shape with the polygon shape shown in Figure 2-52.
Like the
GXSetShapePoints
function discussed in the previous section, theGXSetPolygonParts
function allows you to replace geometric points within a polygon shape's geometry. However, theGXSetPolygonParts
function allows you even more editing control. With it, you can also remove geometric points, insert geometric points, and break a polygon shape into multiple contours.As an example of replacing geometric points in a polygon geometry, the sample function in Listing 2-29 creates two polygon geometries: the two-angle polygon geometry from Figure 2-52 and another polygon geometry consisting of a single point. The sample function creates the two-angle polygon shape as in Listing 2-27 and then replaces its third and fourth geometric points with the single geometric point of the other polygon
geometry.Listing 2-29 Replacing geometric points of a polygon shape
void ReplaceControlPoints(void) { gxShape aPolygonShape; static long twoAngleGeometry[] = {2, /* number of contours */ 3, /* number of points */ ff(100), ff(150), ff(50), ff(100), ff(100), ff(50), 3, /* number of points */ ff(200), ff(50), ff(250), ff(100), ff(200), ff(150)}; static long newTopGeometry[] = {1, /* number of contours */ 1, /* number of points */ ff(150), ff(50)}; aPolygonShape = GXNewPolygons((gxPolygons *) twoAngleGeometry); GXSetShapeFill(aPolygonsShape, gxOpenFrameFill); GXSetPolygonParts(aPolygonShape, 3, 2, (gxPolygons *) newTopGeometry, gxBreakNeitherEdit); GXDrawShape(aPolygonShape); GXDisposeShape(aPolygonShape); }Figure 2-54 shows the result of the sample function in Listing 2-29.Figure 2-54 A polygon with two geometric points replaced by a single geometric point
Notice that, whereas the
GXSetShapePoints
function limited you to replacing geometric points on a point-by-point basis, theGXSetPolygonParts
function allows you to replace any number of geometric points in the original geometry with any number of new geometric points contained in an arbitrary polygon geometry.Since the
GXSetPolygonParts
function allows you to insert an arbitrary polygon geometry into the geometry of an existing polygon shape, you can use this function to break a single polygon contour into multiple contours. In fact, the final parameter toGXSetPolygonParts
allows you to specify how the resulting polygons shape should be broken up. In the previous example, thegxBreakNeitherEdit
constant indicated that the resulting polygon should not be broken into separate contours.The next example, shown in Listing 2-30, first creates a polygon shape similar to the two-angle polygons shape, except in this example the two contours are connected, as shown in Figure 2-55.
Figure 2-55 A polygon shape with one contour
The sample function then uses the
GXSetPolygonParts
function to insert a new geometric point in the center of the polygon.Listing 2-30 Inserting a geometric point in a polygon shape
void CreateHollowPolygon(void) { gxShape aPolygonShape; static long twoAngleGeometry[] = {1, /* number of contours */ 6, /* number of points */ ff(100), ff(150), ff(50), ff(100), ff(100), ff(50), ff(200), ff(50), ff(250), ff(100), ff(200), ff(150)}; static long newCenterGeometry[] = {1, /* number of contours */ 1 /* number of points */, ff(150), ff(100)}; aPolygonShape = GXNewPolygons((gxPolygons *) twoAngleGeometry); GXSetShapeFill(aPolygonShape, gxClosedFrameFill); GXSetPolygonParts(aPolygonShape, 4, 0, (gxPolygons *) newCenterGeometry, gxBreakNeitherEdit); GXDrawShape(aPolygonShape); GXDisposeShape(aPolygonShape); }Since this sample function specifies thegxBreakNeitherEdit
constant as the final parameter to theGXSetPolygonParts
function, the resulting polygon has a single contour, as shown in Figure 2-56.Figure 2-56 A polygon shape edited with the
gxBreakNeitherEdit
flag set
However, if the sample function had specified the
gxBreakLeftEdit
constant, as with the call
GXSetPolygonParts(aPolygonsShape, 4, 0, (gxPolygons *) newCenterGeometry, gxBreakLeftEdit);QuickDraw GX would break the resulting polygon into two contours: ThegxBreakLeftEdit
constant indicates that the polygon should be broken between the newly inserted point and the previous point, as shown in Figure 2-57.Figure 2-57 A polygon shape edited with the
gxBreakLeftEdit
flag set
The
gxBreakRightEdit
constant works similarly, except the break occurs between the newly inserted point and the subsequent point, as shown in Figure 2-58.Figure 2-58 A polygon shape edited with the
gxBreakRightEdit
flag set
You can use the
GXSetPolygonParts
function to insert a polygon geometry that contains multiple contours. In this case, the breaks that occur in the inserted geometry remain in the resulting polygon shape.For more information about polygon geometries, see "Polygon Shapes" on page 2-22.
For more information about the
GXGetPolygonParts
andGXSetPolygonParts
functions, see the function descriptions on page 2-144 and page 2-145.The next two sections show more examples of editing shape geometries.